<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<style>
    *{
        margin: 0;
        padding: 0;
    }
    html,body{
        width: 100%;
        height: 100%;
        display: flex;
        justify-content: center;
    }
    .content{
      /*  width: 200px;/*确保与每个页面大小一致*/
        /*height: 500px;*/
        position: relative;
        overflow: hidden;
        background-color: #1E9FFF;
    }
    .wrapper{
      /*  width: 600px;/*确保是n个页面宽度的n倍*/
        /*/height: 500px;/*确保与页面高度相同*/
        background-color: red;
        display: flex;
        position: absolute;
    }
    .wrapper div{
        /*/width: 200px;/*页面宽度*/
       /*/ height: 500px;/*页面高度*/
        flex-shrink: 0;/*禁止压缩宽度*/
        font-size: 50px;
        text-align:left;
    }
    .wrapper div:nth-child(2n)
    {
        background-color: #c592ff;
    }
</style>
<body>
<div class="content">
    <div class="wrapper">
        <div>1</div>
        <div>2</div>
        <div>3</div>
        <div>4</div>
    </div>
</div>
<button style="visibility: hidden" onclick="removeSlidePageEventListener(document.querySelector('.content'))">移除</button>
<button style="display: none" onclick="add()">添加</button>
</body>
<!--左右滑动翻页-->
<script>
    let emulate=new Array()
    let currentPageNumber=4
    let allPageNumber=10000
    function init() {
      let wrapper=  document.querySelector(".wrapper")
        wrapper.innerHTML=""
        for(let i=0;i<allPageNumber;i++)
           emulate[i]=`<div>哈哈哈哈哈哈哈哈哈${i+1}</div>`
    }
    init()

    /*
    * container:最外层div,一定要是相对定位
    * wrapper:内一层div,一定要是绝对定位+flex布局
    * pages:具体的滑动div数组
    * widthOfPage:页面宽度
    * heightOfPage:页面高度
    * initPageNumber:初始时显示第几页
    * upOperate:翻到上一页动作完成后调用的函数
    * nextOperate:翻到下一页动作完成后调用的函数
    * 参考HTML:
    * <div class="content">
        <div class="wrapper">
            <div>1</div>
            <div>2</div>
            <div>3</div>
            <div>4</div>
        </div>
     </div>
    *参考用法：
    *addSlidePageEventListener(document.querySelector(".content"), document.querySelector(".wrapper"), document.querySelectorAll(".wrapper div"), 200, 600,3,null,null)
    * 不要给元素设置边界等可能影响元素大小、位置等属性的东西
    * **/
    function refreshPageFromWrapper(index) {//index自1开始
        let wrapper=document.querySelector(".wrapper")
        wrapper.style.left=0+"px"
        wrapper.innerHTML=""
        let html=``
        if(index>1)
            html=html+emulate[index-2]
        html=html+emulate[index-1]
        if (index<emulate.length)
            html=html+emulate[index]
        wrapper.innerHTML=html
    }
    function removeSlidePageEventListener(container) {
        let  innerHtml=container.innerHTML
        container.innerHTML=""
        container.innerHTML=innerHtml
    }
    function addSlidePageEventListener(container,wrapper,pages,widthOfPage,heightOfPage,initPageNumber,upOperate,nextOperate) {
        try {
            container.style.width = widthOfPage + "px";
            container.style.height = heightOfPage + "px";
            container.style.overflowX='hidden'
            container.style.overflowY='scroll'
            container.style.position='relative'

            wrapper.style.width = widthOfPage * pages.length + "px";
            wrapper.style.height = heightOfPage + "px";
            wrapper.style.position="absolute"
            wrapper.style.display="flex"
            wrapper.style.border=""//可能会影响宽度，造成难以预料的后果

            for (let i = 0; i < pages.length; i++) {
                pages[i].style.width = widthOfPage + "px";
                pages[i].style.height = heightOfPage + "px";
                pages[i].style.overflowX="hidden"
                pages[i].style.overflowY="scroll"
                pages[i].style.border=""

            }
            // alert(pages.length)
        }catch (e){alert(e)}
        let startDistanceX = '' // 触摸开始X轴位置
        let startDistanceY = '' // 触摸开始Y轴位置
        let endDistanceX = '' // 触摸结束X轴位置
        let endDistanceY = '' // 触摸结束Y轴位置
        let moveDistanceX = '' // 触摸移动X轴距离
        let moveDistanceY = '' // 触摸移动Y轴距离
        if(initPageNumber>=1&&initPageNumber<=pages.length)
        {
            wrapper.style.left=wrapper.offsetLeft-(initPageNumber)*widthOfPage+"px"
        }

        let wrapperAbsolutePosition=wrapper.offsetLeft


        container.addEventListener("touchstart",touchstart)
        //按住ctrl,鼠标点击addEventListener()查看源码，里面的interface GlobalEventHandlersEventMap有包含多少事件
        container.addEventListener("touchmove",touchmove)

        container.addEventListener("touchend",touchend)
        /*定义回调函数*/
        function touchstart(e) {
            startDistanceX = e.touches[0].screenX
            startDistanceY = e.touches[0].screenY
            wrapperAbsolutePosition=wrapper.offsetLeft
            //console.log("最基本位置"+wrapperAbsolutePosition)
        }

        function touchmove(e) {
            let X=e.changedTouches[0].screenX
            let Δx=X-startDistanceX//相对位移
            let Y=e.changedTouches[0].screenY
            let Δy=Y-startDistanceY
            if((Math.abs(Δx)>(Math.abs(Δy))))
                //在存在上/下一页的清空下不断位移不断位移
                if((Δx>0&&haveUpPage())||(Δx<0&&haveNextPage())) {
                    wrapper.style.left = wrapperAbsolutePosition + Δx + "px"
                }
        }
        function touchend(e) {
            endDistanceX = e.changedTouches[0].screenX
            endDistanceY = e.changedTouches[0].screenY

            moveDistanceX = startDistanceX - endDistanceX//当大于0时说明是划向下一页
            moveDistanceY = startDistanceY - endDistanceY

            /*一定要在设置style.left时确保前后值>=0.5,不然可能设置了但是没效果*/
            if (((Math.abs(moveDistanceX) > widthOfPage/3))&&(Math.abs(moveDistanceX)>Math.abs(moveDistanceY))) {//翻页
                if((moveDistanceX>0&&!haveNextPage())||(moveDistanceX<0&&!haveUpPage()))
                    return//处于第一页/最后一页
                /*移除事件监听器，防止在滑动过程中又滑动*/
                container.removeEventListener("touchstart",touchstart,false)
                container.removeEventListener("touchmove",touchmove,false)
                container.removeEventListener("touchend",touchend,false)
                //wrapper最终位置:save
                //翻到上一页时，wrapper当前位置一定小于最终位置
                let save=wrapperAbsolutePosition+widthOfPage//上一页
                if(moveDistanceX>0) //下一页
                    save=wrapperAbsolutePosition-widthOfPage

                //     console.log("初始最终位置："+save)
                let t=setInterval(()=>{ //更新wrapper位置
                    if(moveDistanceX>0&&wrapperAbsolutePosition>=save)//下一页
                    {
                        //  alert("s")
                        let offset = -widthOfPage / 40 - 0.1
                        wrapperAbsolutePosition=wrapper.offsetLeft+offset
                        if(wrapperAbsolutePosition>=save)
                            wrapper.style.left=wrapperAbsolutePosition+"px"
                        else
                        {
                            wrapper.style.left=save+"px"
                            //   console.log("结束时最终位置："+save+"位置："+wrapper.style.left)
                            clearInterval(t)
                            nextOperate()
                        }

                    }
                    else if((moveDistanceX<0&&wrapperAbsolutePosition<=save))//上一页
                    {//alert("o")
                        let offset=widthOfPage/40+0.1
                        wrapperAbsolutePosition=wrapper.offsetLeft+offset
                        if(wrapperAbsolutePosition<=save)
                            wrapper.style.left=wrapperAbsolutePosition+"px"
                        else
                        {

                            wrapper.style.left=save+"px"
                            //   console.log("结束时最终位置："+save+"位置："+wrapper.style.left)
                            clearInterval(t)
                            upOperate()
                        }

                    }
                },2)
            }
            else//距离不足，回到原位置
            {
                if (moveDistanceX !== 0&&(wrapper.offsetLeft!==wrapperAbsolutePosition)) {
                    /*移除事件监听器，防止在滑动过程中又滑动*/
                    container.removeEventListener("touchstart", touchstart, false)
                    container.removeEventListener("touchmove", touchmove, false)
                    container.removeEventListener("touchend", touchend, false)
                    let save = wrapperAbsolutePosition//最终位置
                    //开始移动
                    let t = setInterval(() => {
                        //从手指离开位置开始滑动回到原位置
                        // console.log(moveDistanceX+"\n"+wrapperAbsolutePosition+"\n"+save)
                        wrapperAbsolutePosition = wrapper.offsetLeft
                        if ((moveDistanceX>0&&wrapperAbsolutePosition>=save)||(moveDistanceX<0&&wrapperAbsolutePosition<=save))
                        {
                            wrapper.style.left = save + "px"
                            clearInterval(t)
                            container.addEventListener("touchstart", touchstart)
                            //按住ctrl,鼠标点击addEventListener()查看源码，里面的interface GlobalEventHandlersEventMap有包含多少事件
                            container.addEventListener("touchmove", touchmove)
                            container.addEventListener("touchend", touchend)

                        }
                        else {
                            let offset = 0.5
                            if (moveDistanceX < 0)//回退方向
                                offset = -offset
                            wrapperAbsolutePosition = wrapper.offsetLeft + moveDistanceX / 20 + offset
                            wrapper.style.left = wrapperAbsolutePosition + "px"
                        }
                    }, 2)

                }
            }
        }
        //
        function haveNextPage() {
            if(wrapper.offsetLeft>-widthOfPage*(pages.length-1))
                return true;
            return false
        }
        function haveUpPage() {
            if(wrapper.offsetLeft<0)
                return true
            return false
        }

    }

    function getPage(index) {
        refreshPageFromWrapper(index)
        removeSlidePageEventListener(document.querySelector(".content"))
        let i=1
        if(index===1)
            i=0
        console.log(index)
        addSlidePageEventListener(document.querySelector(".content"), document.querySelector(".wrapper"), document.querySelectorAll(".wrapper div"), 200, 600,i,function () {
                if(currentPageNumber>1){
                getPage(currentPageNumber - 1)
                currentPageNumber--}

        },function () {
            if(currentPageNumber<allPageNumber){
            getPage(currentPageNumber+1)
            currentPageNumber++}

        })
    }
    getPage(currentPageNumber)

</script>


</html>